﻿using System;
using System.Collections.Generic;
using System.Web;
using Autofac;
using System.Linq;
using SlamCms.Common;

namespace SlamCms.SharePoint
{
	public abstract class Bootstrapper
	{	
		public virtual void PreApplicationStart(PreApplicationStartContext context)
		{ }

		public virtual void PostApplicationStart(PostApplicationStartContext context)
		{ }

		public static void Run(HttpApplication httpApplication)
		{
			var bootstrappers = GetBootstrappers().ToList();

			var builder = new ContainerBuilder();

			var preApplicationStartContext = new PreApplicationStartContext()
			{
				Application = httpApplication,
				ContainerBuilder = builder
			};

			bootstrappers.ForEach(b => b.PreApplicationStart(preApplicationStartContext));

			var container = builder.Build();

			var postApplicationStartContext = new PostApplicationStartContext()
			{
				Application = httpApplication,
				Container = container
			};

			bootstrappers.ForEach(b => b.PostApplicationStart(postApplicationStartContext));
		}

		private static IEnumerable<Bootstrapper> GetBootstrappers()
		{
			var list = new List<Bootstrapper>();

			foreach (var bootstrapperType in GetBootstrapperTypes())
			{
				var instance = GetBootstrapperInstance(bootstrapperType);
				list.Add(instance);
			}

			return list;
		}

		private static Bootstrapper GetBootstrapperInstance(Type bootstrapperType)
		{
			var instance = bootstrapperType.CreateInstance<Bootstrapper>();

			if (instance == null)
				throw new Exception("Cannot create instance of Bootstrapper: {0}".F(bootstrapperType.FullName));

			return instance;
		}

		private static IEnumerable<Type> GetBootstrapperTypes()
		{
			return TypeHelpers.GetFilteredTypesFromAssemblies(t => t != typeof(Bootstrapper) && typeof(Bootstrapper).IsAssignableFrom(t)).OrderBy(t => t.Name);
		}
	}
}